home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
051-075
/
scopedisk75
/
ispell
/
src
/
ispell.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
12KB
|
695 lines
/* -*- Mode:Text -*- */
/*
* ispell.c - An interactive spelling corrector.
*
* Copyright (c), 1983, by Pace Willisson
* Permission for non-profit use is hereby granted.
* All other rights reserved.
*/
#include <stdio.h>
#include <ctype.h>
#include "ispell.h"
#define NOPARITY 0x7f
FILE *infile;
FILE *outfile;
givehelp ()
{
erase ();
printf ("Whenever a word is found that is not in the dictionary,\r\n");
printf ("it is printed on the first line of the screen. If the dictionary\r\n");
printf ("contains any similar words, they are listed with a single digit\r\n");
printf ("next to each one. You have the option of replacing the word\r\n");
printf ("completely, or choosing one of the suggested words.\r\n");
printf ("\r\n");
printf ("Commands are:\r\n\r\n");
printf ("R Replace the misspelled word completely.\r\n");
printf ("Space Accept the word this time only\r\n");
printf ("A Accept the word for the rest of this file.\r\n");
printf ("I Accept the word, and put it in your private dictionary.\r\n");
printf ("0-9 Replace with one of the suggested words.\r\n");
printf ("Q Write the rest of this file, ignoring misspellings, ");
printf ( "and start next file.\r\n");
printf ("X Exit immediately. Asks for conformation. ");
printf ( "Leaves file unchanged.\r\n");
printf ("! Shell escape.\r\n");
printf ("^L Redraw screen.\r\n");
printf ("\r\n\r\n");
printf ("-- Type space to continue --");
fflush (stdout);
getchar ();
}
char *getline();
int lflag = 0;
int aflag = 0;
int fflag = 0;
int sflag = 0;
char *askfilename;
usage ()
{
fprintf (stderr, "Usage: spell [ file ... | -a | -l | -f file | -s ]\n");
exit (1);
}
main (argc, argv)
char **argv;
{
argv++;
argc--;
while (argc && **argv == '-') {
switch ((*argv)[1]) {
case 'a':
aflag++;
break;
case 'f':
fflag++;
argv++; argc--;
if (argc == 0)
usage ();
askfilename = *argv;
break;
case 'l':
lflag++;
break;
case 's':
sflag++;
break;
}
argv++; argc--;
}
if (!argc && !lflag && !aflag)
usage ();
if (linit () < 0)
exit (0);
treeinit ();
if (aflag) {
askmode ();
exit (0);
}
if (lflag) {
infile = stdin;
checkfile ();
exit (0);
}
terminit ();
while (argc--)
dofile (*argv++);
done ();
}
char firstbuf[BUFSIZ], secondbuf[BUFSIZ];
char *currentchar;
char token[BUFSIZ];
int quit;
char *currentfile = NULL;
dofile (filename)
char *filename;
{
int c;
char bakfile[256];
currentfile = filename;
if ((infile = fopen (filename, "r")) == NULL) {
fprintf (stderr, "Can't open %s\r\n", filename);
sleep (2);
return;
}
if (access (filename, 2) < 0) {
fprintf (stderr, "Can't write to %s\r\n", filename);
sleep (2);
return;
}
#ifndef AMIGA
strcpy (tempfile, "/usr/tmp/spellXXXXXX");
#else
strcpy(tempfile, TMPDIR);
#if USEDEVICES
strcat(tempfile, "ispellXXXXXX");
#else
strcat(tempfile, "/ispellXXXXXX");
#endif
#endif
mktemp (tempfile);
if ((outfile = fopen (tempfile, "w")) == NULL) {
fprintf (stderr, "Can't create %s\r\n", tempfile);
sleep (2);
return;
}
quit = 0;
checkfile ();
fclose (infile);
fclose (outfile);
treeoutput ();
if ((infile = fopen (tempfile, "r")) == NULL) {
fprintf (stderr, "tempoary file disappeared (%s)\r\n", tempfile);
sleep (2);
return;
}
sprintf(bakfile, "%s.bak", filename);
if(link(filename, bakfile) == 0)
unlink(filename);
if ((outfile = fopen (filename, "w")) == NULL) {
fprintf (stderr, "can't create %s\r\n", filename);
sleep (2);
return;
}
while ((c = getc (infile)) != EOF)
putc (c, outfile);
fclose (infile);
fclose (outfile);
unlink (tempfile);
}
checkfile ()
{
int c;
char *p;
int len;
secondbuf[0] = 0;
currentchar = secondbuf;
while (1) {
strcpy (firstbuf, secondbuf);
if (quit) { /* quit can't be set in l mode */
while (fgets (secondbuf, sizeof secondbuf, infile) != NULL)
fputs (secondbuf, outfile);
break;
}
if (fgets (secondbuf, sizeof secondbuf, infile) == NULL)
break;
currentchar = secondbuf;
len = strlen (secondbuf) - 1;
if (secondbuf [ len ] == '\n')
secondbuf [ len ] = 0;
/* if this is a formatter command, skip over it */
if (*currentchar == '.') {
while (*currentchar && !isspace (*currentchar)) {
if (!lflag)
putc (*currentchar, outfile);
currentchar++;
}
if (*currentchar == 0) {
putc ('\n', outfile);
continue;
}
}
while (1) {
while (*currentchar && !isalpha (*currentchar)) {
/* formatting escape sequences */
if (*currentchar == '\\') {
if(currentchar[1] == 'f') {
/* font change: \fX */
copyout(¤tchar, 3);
continue;
}
else if(currentchar[1] == 's') {
/* size change */
if(currentchar[2] < 6 &&
currentchar[2] != 0)
/* two digit size */
copyout(¤tchar, 4);
else
/* one digit size */
copyout(¤tchar, 3);
continue;
}
else if(currentchar[1] == '(') {
/* extended char set escape: \(XX */
copyout(¤tchar, 4);
continue;
}
}
if (!lflag)
putc (*currentchar, outfile);
currentchar++;
}
if (*currentchar == 0)
break;
p = token;
while (isalpha (*currentchar))
*p++ = *currentchar++;
*p = 0;
if (lflag) {
if (!good (token))
printf ("%s\r\n", token);
} else {
if (!quit)
correct (token, ¤tchar);
}
if (!lflag)
fprintf (outfile, "%s", token);
}
putc ('\n', outfile);
}
}
char possibilities[10][BUFSIZ];
int pcount;
correct (token, currentchar)
char *token;
char **currentchar;
{
int c;
int i;
char *p;
int len;
char *begintoken;
len = strlen (token);
begintoken = *currentchar - len;
checkagain:
if (good (token))
return;
erase ();
printf (" %s", token);
if (currentfile)
printf (" File: %s", currentfile);
printf ("\r\n\r\n");
makepossibilities (token);
for (i = 0; i < 10; i++) {
if (possibilities[i][0] == 0)
break;
printf ("%d: %s\r\n", i, possibilities[i]);
}
move (15, 0);
printf ("%s\r\n", firstbuf);
for (p = secondbuf; p != begintoken; p++)
putchar (*p);
inverse ();
for (i = strlen (token); i > 0; i--)
putchar (*p++);
normal ();
while (*p)
putchar (*p++);
printf ("\r\n");
while (1) {
switch (c = (getchar () & NOPARITY)) {
case 'Z' & 037:
stop ();
erase ();
goto checkagain;
case ' ':
erase ();
return;
case 'x': case 'X':
printf ("Are you sure you want to throw away your changes? ");
c = (getchar () & NOPARITY);
if (c == 'y' || c == 'Y') {
erase ();
done ();
}
putchar (7);
goto checkagain;
case 'i': case 'I':
treeinsert (token, 1);
erase ();
return;
case 'a': case 'A':
treeinsert (token, 0);
erase ();
return;
case 'L' & 037:
goto checkagain;
case '?':
givehelp ();
goto checkagain;
case '!':
{
char buf[200];
move (18, 0);
putchar ('!');
if (getline (buf) == NULL) {
putchar (7);
erase ();
goto checkagain;
}
printf ("\r\n");
shellescape (buf);
erase ();
goto checkagain;
}
case 'r': case 'R':
move (18, 0);
printf ("Replace with: ");
if (getline (token) == NULL) {
putchar (7);
erase ();
goto checkagain;
}
inserttoken (secondbuf, begintoken, token, currentchar);
erase ();
goto checkagain;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (possibilities[c - '0'][0] != 0) {
strcpy (token, possibilities[c - '0']);
inserttoken (secondbuf, begintoken, token, currentchar); erase ();
return;
}
putchar (7);
break;
case 'q': case 'Q':
quit = 1;
erase ();
return;
default:
putchar (7);
break;
}
}
}
inserttoken (buf, start, token, currentchar)
char *buf, *start, *token;
char **currentchar;
{
char copy[BUFSIZ];
char *p, *q;
strcpy (copy, buf);
for (p = buf, q = copy; p != start; p++, q++)
*p = *q;
while (*token)
*p++ = *token++;
q += *currentchar - start;
*currentchar = p;
while (*p++ = *q++)
;
}
makepossibilities (word)
char word[];
{
int i;
for (i = 0; i < 10; i++)
possibilities[i][0] = 0;
pcount = 0;
if (pcount < 10) wrongletter (word);
if (pcount < 10) extraletter (word);
if (pcount < 10) missingletter (word);
if (pcount < 10) transposedletter (word);
}
char *cap();
insert (word)
char *word;
{
int i;
for (i = 0; i < pcount; i++)
if (strcmp (possibilities[i], word) == 0)
return (0);
strcpy (possibilities[pcount++], word);
if (pcount >= 10)
return (-1);
else
return (0);
}
wrongletter (word)
char word[];
{
int i, c, n;
char newword[BUFSIZ];
n = strlen (word);
strcpy (newword, word);
for (i = 0; i < n; i++) {
for (newword[i] = 'A'; newword[i] <= 'Z'; newword[i]++) {
if (good (newword)) {
if (insert (cap (newword, word)) < 0)
return;
}
}
newword[i] = word[i];
}
}
extraletter (word)
char word[];
{
char newword[BUFSIZ], *p, *s, *t;
if (strlen (word) < 3)
return;
for (p = word; *p; p++) {
for (s = word, t = newword; *s; s++)
if (s != p)
*t++ = *s;
*t = 0;
if (good (newword)) {
if (insert (cap (newword, word)) < 0)
return;
}
}
}
missingletter (word)
char word[];
{
char newword[BUFSIZ], *p, *r, *s, *t;
for (p = word; p == word || p[-1]; p++) {
for (s = newword, t = word; t != p; s++, t++)
*s = *t;
r = s++;
while (*t)
*s++ = *t++;
*s = 0;
for (*r = 'A'; *r <= 'Z'; (*r)++) {
if (good (newword)) {
if (insert (cap (newword, word)) < 0)
return;
}
}
}
}
transposedletter (word)
char word[];
{
char newword[BUFSIZ];
int t;
char *p;
strcpy (newword, word);
for (p = newword; p[1]; p++) {
t = p[0];
p[0] = p[1];
p[1] = t;
if (good (newword)) {
if (insert (cap (newword, word)) < 0)
return;
}
t = p[0];
p[0] = p[1];
p[1] = t;
}
}
char *
cap (word, pattern)
char word[], pattern[];
{
static char newword[BUFSIZ];
char *p, *q;
if (*word == 0)
return;
if (isupper (pattern[0])) {
if (isupper (pattern[1])) {
for (p = word, q = newword; *p; p++, q++) {
if (islower (*p))
*q = toupper (*p);
else
*q = *p;
}
*q = 0;
} else {
if (islower (word [0]))
newword[0] = toupper (word[0]);
else
newword[0] = word[0];
for (p = word + 1, q = newword + 1; *p; p++, q++)
if (isupper (*p))
*q = tolower (*p);
else
*q = *p;
*q = 0;
}
} else {
for (p = word, q = newword; *p; p++, q++)
if (isupper (*p))
*q = tolower (*p);
else
*q = *p;
*q = 0;
}
return (newword);
}
char *
getline (s)
char *s;
{
char *p;
int c;
p = s;
while (1) {
c = (getchar () & NOPARITY);
if (c == '\\') {
putchar ('\\');
c = (getchar () & NOPARITY);
backup ();
putchar (c);
*p++ = c;
} else if (c == ('G' & 037)) {
return (NULL);
} else if (c == '\n' || c == '\r') {
*p = 0;
return (s);
} else if (c == erasechar) {
if (p != s) {
p--;
backup ();
putchar (' ');
backup ();
}
} else if (c == killchar) {
while (p != s) {
p--;
backup ();
putchar (' ');
backup ();
}
} else {
*p++ = c;
putchar (c);
}
}
}
askmode ()
{
char buf[BUFSIZ];
int i;
if (fflag) {
if (freopen (askfilename, "w", stdout) == NULL) {
fprintf (stderr, "Can't create %s\n", askfilename);
exit (1);
}
}
setbuf (stdin, NULL);
setbuf (stdout, NULL);
while (gets (buf) != NULL) {
if (good (buf)) {
if (rootword[0] == 0) {
printf ("*\n"); /* perfect match */
} else {
printf ("+ %s\n", rootword);
}
} else {
makepossibilities (buf);
if (possibilities[0][0]) {
printf ("& ");
for (i = 0; i < 10; i++) {
if (possibilities[i][0] == 0)
break;
printf ("%s ", possibilities[i]);
}
printf ("\n");
} else {
printf ("#\n");
}
}
if (sflag) {
stop ();
if (fflag) {
rewind (stdout);
creat (askfilename, 0666);
}
}
}
}
copyout(cc, cnt)
char **cc;
{
while (--cnt >= 0) {
if (*(*cc) == 0)
break;
if (!lflag)
putc (*(*cc), outfile);
(*cc)++;
}
}